module espi_cpld (
inout espi_host_io0,
inout espi_host_io1,
inout espi_host_io2,
inout espi_host_io3,
//output ham_espi_cs_n,
input espi_cs_n_i,
output espi_host_alert_o,
//input  ham_alert_i,
output           uart_tx_o        ,
input            uart_rx_i        ,

input espi_clk,
input espi_rst_n,
input uart_clk,
input uart_rst_n,
input rst_pltrst_pld_n
);
parameter SINGLE_IO =0;
parameter QUAD_IO =1;

reg espi_cpld_io0_oe;
reg espi_cpld_io1_oe;
reg espi_cpld_io2_oe;
reg espi_cpld_io3_oe;

reg espi_cpld_io0_o;
reg espi_cpld_io1_o;
reg espi_cpld_io2_o;
reg espi_cpld_io3_o;
wire io1_alert_oe;
assign espi_host_io0 = espi_cpld_io0_oe ? espi_cpld_io0_o :1'bz;
assign espi_host_io1 = (espi_cpld_io1_oe || io1_alert_oe) ? espi_cpld_io1_o :1'bz;
assign espi_host_io2 = espi_cpld_io2_oe ? espi_cpld_io2_o :1'bz;
assign espi_host_io3 = espi_cpld_io3_oe ? espi_cpld_io3_o :1'bz;

reg start_int;
reg espi_alert_n;
reg io1_alert_n;
//assign espi_host_alert_o = start_int ? espi_alert_n : ham_alert_i;

assign espi_host_alert_o =  espi_alert_n ;

//assign io1_alert_o       = start_int ? io1_alert_n : 1'bz;
assign io1_alert_oe      = start_int ?  !io1_alert_n : 1'b0;

wire  espi_host_io0_i = espi_host_io0;
wire  espi_host_io1_i = espi_host_io1;
wire  espi_host_io2_i = espi_host_io2;
wire  espi_host_io3_i = espi_host_io3;
reg   ham_cs_n_temp;

//assign ham_espi_cs_n = espi_cs_n_i || ham_cs_n_temp;

 reg [7:0] rx_shift_bit_cnt;
 reg [7:0] tx_shift_bit_cnt;
reg [15:0] espi_addr;
reg [7:0] command;
reg espi_host_io_mode ;
reg alert_en;

always @(posedge espi_clk or posedge espi_cs_n_i) begin
   if(espi_cs_n_i) begin
      rx_shift_bit_cnt <=0;
   end
   else begin
      rx_shift_bit_cnt <= rx_shift_bit_cnt +1;
   end
end

always @(negedge espi_clk or posedge espi_cs_n_i) begin
   if(espi_cs_n_i) begin
      tx_shift_bit_cnt <=0;
   end
   else begin
      tx_shift_bit_cnt <= tx_shift_bit_cnt +1;
   end
end



always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) command <=0;
   else case(espi_host_io_mode)
         SINGLE_IO:
            if(rx_shift_bit_cnt[7:3]== 5'h0) command <= {command[6:0],espi_host_io0_i};
         QUAD_IO : if(rx_shift_bit_cnt[7:1] == 7'h0) command <= {command[3:0],espi_host_io3_i,espi_host_io2_i,espi_host_io1_i,espi_host_io0_i};
         default : command <= command;
   endcase
end

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) espi_addr <=0;
   else case(espi_host_io_mode)
      SINGLE_IO:
         if(rx_shift_bit_cnt[7:3] == 1 || rx_shift_bit_cnt[7:3] ==2 ) espi_addr <= {espi_addr[15:0],espi_host_io0_i};
      QUAD_IO : if(rx_shift_bit_cnt[7:1] == 1 || rx_shift_bit_cnt[7:1] ==2 ) espi_addr <= {espi_addr[11:0],espi_host_io3_i,espi_host_io2_i,espi_host_io1_i,espi_host_io0_i};
      default : espi_addr <= espi_addr;
   endcase
end


reg [7:0] espi_cap_config;
always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) espi_cap_config <= 8'h23;
   else if(espi_host_io_mode == SINGLE_IO && command == 8'h22 && espi_addr == 8'h08) begin
        if(rx_shift_bit_cnt[7:3] == 6 ) espi_cap_config[7:0]<={espi_cap_config[6:0],espi_host_io0_i};
   end
   else if(espi_host_io_mode == QUAD_IO && command == 8'h22 && espi_addr == 8'h08) begin
        if(rx_shift_bit_cnt[7:1] == 6 ) espi_cap_config[7:0]<= {espi_cap_config[3:0],espi_host_io3_i,espi_host_io2_i,espi_host_io1_i,espi_host_io0_i};
   end
end   

reg [7:0] uart_wrdata;
always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) uart_wrdata <= 8'h0;
   else if(espi_host_io_mode == SINGLE_IO && command == 8'h44 && espi_addr[15:3] == (16'h03f8>>3)) begin
      if(rx_shift_bit_cnt[7:3] == 3 ) uart_wrdata[7:0]<={uart_wrdata[6:0],espi_host_io0_i};
      //else if(rx_shift_bit_cnt[7:0] == 8'h27)begin
      //   uart_wrdata[2:1] <= 2'b0;
      //end
   end
   else if(espi_host_io_mode == QUAD_IO && command == 8'h44 && espi_addr[15:3] == 16'h03f8>>3) begin
      if(rx_shift_bit_cnt[7:1] == 3 ) uart_wrdata[7:0]<= {uart_wrdata[3:0],espi_host_io3_i,espi_host_io2_i,espi_host_io1_i,espi_host_io0_i};
      //else if(rx_shift_bit_cnt == 8'hF)begin
      //   uart_wrdata[2:1] <= 2'b0;
      //end
   end
   //else begin
   //   uart_wrdata[2:1] <= 2'b0;
   //end
end   

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) begin
      espi_host_io_mode <= 0;
      alert_en <= 1'b1;
   end
   else if(espi_host_io_mode == SINGLE_IO && rx_shift_bit_cnt == 8'h60 && command == 8'h22) begin
      espi_host_io_mode <= espi_cap_config[3];
      alert_en <= espi_cap_config[4];
   end
   else if(espi_host_io_mode == QUAD_IO && rx_shift_bit_cnt == 8'h18 && command == 8'h22 ) begin
      espi_host_io_mode <= espi_cap_config[3];
      alert_en <= espi_cap_config[4];
   end
end

reg uart_write;
reg uart_write_d1;
reg uart_write_d2;
reg uart_write_d3;
reg uart_read;
reg uart_read_d1;
reg uart_read_d2;
reg uart_read_d3;
always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      uart_write_d1 <= 1'b0;
      uart_write_d2 <= 1'b0;
      uart_write_d3 <= 1'b0;
      uart_read_d1 <= 1'b0;
      uart_read_d2 <= 1'b0;
      uart_read_d3 <= 1'b0;
   end
   else begin
      uart_write_d1 <= uart_write; 
      uart_write_d2 <= uart_write_d1;
      uart_write_d3 <= uart_write_d2;
      uart_read_d1 <=  uart_read;
      uart_read_d2 <=  uart_read_d1;
      uart_read_d3 <=  uart_read_d2;
   end
end

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n)  uart_write <= 1'b0;
   else if(espi_host_io_mode == SINGLE_IO && command == 8'h44 && espi_addr[15:3] == 13'h7F ) begin
      uart_write <= (rx_shift_bit_cnt == 8'h30);
   end
   else if(espi_host_io_mode == QUAD_IO && command == 8'h44 && espi_addr[15:3] == 13'h7F ) begin
      uart_write <= (rx_shift_bit_cnt == 8'hb);
   end
   else begin
      uart_write <= 1'b0;
   end
end

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n)  uart_read <= 1'b0;
   else if(espi_host_io_mode == SINGLE_IO && command == 8'h40 && espi_addr[15:3] == 13'h7F) begin
      uart_read <= (rx_shift_bit_cnt == 8'h20);
   end
   else if(espi_host_io_mode == QUAD_IO && command == 8'h40 && espi_addr[15:3] == 13'h7F) begin
      uart_read <= (rx_shift_bit_cnt == 8'h8);
   end
   else begin
      uart_read <= 1'b0;
   end
end

wire uart_ren;
wire uart_wren;
reg uart_data_vld;
reg [7:0] uart_rddata;
wire [7:0] uart_rdout;
always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      uart_data_vld <= 1'b0;
   end
   else begin
      uart_data_vld <= uart_ren;
   end
end

always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      uart_rddata <= 8'b0;
   end
   else if(uart_data_vld) begin
      uart_rddata <= uart_rdout;
   end
end
 
assign uart_ren = uart_read_d2 && !uart_read_d3;
assign uart_wren = uart_write_d2 && !uart_write_d3;

reg [7:0] espi_put_vwire_data /*synthesis noprune*/;
reg system_event /*synthesis noprune*/;
always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) espi_put_vwire_data <=0;
   else case(espi_host_io_mode)
      SINGLE_IO:
         if(rx_shift_bit_cnt[7:3] != 0 && command== 8'h04 ) espi_put_vwire_data <= {espi_put_vwire_data[6:0],espi_host_io0_i};
      //QUAD_IO : if(rx_shift_bit_cnt[7:1] == 1 || rx_shift_bit_cnt[7:1] ==2 ) espi_addr <= {espi_addr[11:0],espi_host_io3_i,espi_host_io2_i,espi_host_io1_i,espi_host_io0_i};
      //default : espi_addr <= espi_addr;
   endcase
end

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) system_event <= 1'b0;
   else if(command == 8'h04) begin 
      if(rx_shift_bit_cnt == 8'h18 || rx_shift_bit_cnt == 8'h28 ||  rx_shift_bit_cnt == 8'h38)  begin
         if(espi_put_vwire_data == 8'h02 || espi_put_vwire_data == 8'h03 || espi_put_vwire_data == 8'h41) begin
	    system_event <= 1'b1;
	 end
      end
   end
   else begin
      system_event <= 1'b0;
   end
 end

reg  rst_pltrst_pld_n_t;
reg  rst_pltrst_pld_n_t1;
reg  system_event_t;
reg  system_event_t1;

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) begin 
		rst_pltrst_pld_n_t <= 1'b0; 
		rst_pltrst_pld_n_t1 <= 1'b0;
		system_event_t <= system_event;
   end
   else  begin
      rst_pltrst_pld_n_t <= rst_pltrst_pld_n;
      rst_pltrst_pld_n_t1 <= rst_pltrst_pld_n_t;
      system_event_t1 <= system_event_t;
   end
end

always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) start_int <= 1'b0;
   // else if(rst_pltrst_pld_n_t1 & ~rst_pltrst_pld_n_t) start_int <= 1'b0;
   else if((espi_host_io_mode == SINGLE_IO && rx_shift_bit_cnt == 8'h20 && command == 8'h04) || (espi_host_io_mode == QUAD_IO && rx_shift_bit_cnt == 8'h08 && command == 8'h04)) start_int <= 1'b0;
   else if(command == 8'h44 && espi_addr == 16'h03f9) begin
      start_int <= 1'b1;
   end
end
//always @(negedge espi_clk or negedge espi_rst_n) begin
//   if(!espi_rst_n)  espi_host_io1_oe <= 1'b0;
//   //else if(espi_host_io_mode == SINGLE_IO && command == 8'h44 ) begin
//   //   espi_host_io1_oe <= (rx_shift_bit_cnt == 8'h2a);
//   //end
//   //else begin
//   //   espi_host_io1_oe <= 1'b0;
//   //end
//end

wire [7:0] tx_shift_bit_cnt_m1 = tx_shift_bit_cnt -8'h21;
wire [7:0] tx_shift_bit_cnt_m2 = tx_shift_bit_cnt -8'h11;
always @(negedge espi_clk or posedge espi_cs_n_i) begin
   if(espi_cs_n_i) ham_cs_n_temp <= 1'b0;
   else if(espi_host_io_mode == SINGLE_IO) begin
      if(command == 8'h40) begin
         if( espi_addr[15:3] == 13'h7F) begin
            if(tx_shift_bit_cnt == 8'h20) ham_cs_n_temp <= 1'b1;
         end
         else begin
            if(tx_shift_bit_cnt == 8'h31) ham_cs_n_temp <= 1'b1;
         end
      end
      else if(command == 8'h44) begin
         if(espi_addr[15:3] == 13'h7F) begin
            if(tx_shift_bit_cnt == 8'h28) ham_cs_n_temp <= 1'b1;
         end
         else begin
            if(tx_shift_bit_cnt == 8'h31) ham_cs_n_temp <= 1'b1;
         end
      end
      else if(command == 8'h05 && start_int) begin
         if( tx_shift_bit_cnt == 8'h10)  ham_cs_n_temp <= 1'b1;
      end
      else if(command == 8'h25 && start_int) begin
         if( tx_shift_bit_cnt == 8'h10)  ham_cs_n_temp <= 1'b1;
      end
      else begin
         ham_cs_n_temp <=1'b0;
      end
   end
   else begin
      if(command == 8'h40) begin
         if( espi_addr[15:3] == 13'h7F) begin
            if(tx_shift_bit_cnt == 8'h8) ham_cs_n_temp <= 1'b1;
         end
         else begin
            if(tx_shift_bit_cnt == 8'hd) ham_cs_n_temp <= 1'b1;
         end
      end
      else if(command == 8'h44) begin
         if(espi_addr[15:3] == 13'h7F) begin
            if(tx_shift_bit_cnt == 8'ha) ham_cs_n_temp <= 1'b1;
         end
         else begin
            if(tx_shift_bit_cnt == 8'hd) ham_cs_n_temp <= 1'b1;
         end
      end
      else if(command == 8'h05 && start_int) begin
         if( tx_shift_bit_cnt == 8'h04)  ham_cs_n_temp <= 1'b1;
      end
      else if(command == 8'h25 && start_int) begin
         if( tx_shift_bit_cnt == 8'h04)  ham_cs_n_temp <= 1'b1;
      end
      else begin
         ham_cs_n_temp <=1'b0;
      end
   end
end

parameter ACCEPT =8'h8;

wire uart_int;
reg uart_int_ff1;
reg uart_int_ff2;
reg uart_int_ff3;
reg uart_int_status;
always @(negedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) begin
      uart_int_ff1 <= 1'b0;
      uart_int_ff2 <= 1'b0;
      uart_int_ff3 <= 1'b0;
   end
   else begin
      uart_int_ff1 <= uart_int;
      uart_int_ff2 <= uart_int_ff1;
      uart_int_ff3 <= uart_int_ff2;
   end
end

always @(negedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) uart_int_status <= 1'b0;
   else if(command == 8'h05 && start_int ) uart_int_status <= 1'b0;
   else if(uart_int_ff2 && !uart_int_ff3) begin
      uart_int_status <= 1'b1;
   end
end


reg uart_int_d1;
reg uart_int_d2;
reg uart_int_d3;

reg espi_cs_n_i_ff1;
reg espi_cs_n_i_ff2;
reg espi_cs_n_i_ff3;
reg uart_alert;

reg ham_cs_n_temp_d1;
reg ham_cs_n_temp_d2;
reg ham_cs_n_temp_d3;
always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      uart_int_d1 <=1'b0;
   end
   else begin
      uart_int_d1 <= uart_int;
   end
end

always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      ham_cs_n_temp_d1 <=1'b0;
      ham_cs_n_temp_d2 <=1'b0;
      ham_cs_n_temp_d3 <= 1'b0;
   end
   else begin
      ham_cs_n_temp_d1 <= ham_cs_n_temp;
      ham_cs_n_temp_d2 <= ham_cs_n_temp_d1;
      ham_cs_n_temp_d3 <= ham_cs_n_temp_d2;
   end
end

always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      uart_alert <= 1'b0;
   end
   else if(uart_int && !uart_int_d1) begin
      uart_alert <= 1'b1;
   end
   else if((command == 8'h40 || command == 8'h44 || command == 8'h05 || command == 8'h25) && ham_cs_n_temp_d2 && !ham_cs_n_temp_d3) begin
      uart_alert <= 1'b0;
   end
end

always @(posedge uart_clk or negedge uart_rst_n) begin
   if(!uart_rst_n) begin
      espi_cs_n_i_ff1 <=1;
      espi_cs_n_i_ff2 <=1;
      espi_cs_n_i_ff3 <= 1;
   end
   else begin
      espi_cs_n_i_ff1 <= espi_cs_n_i;
      espi_cs_n_i_ff2 <= espi_cs_n_i_ff1;
      espi_cs_n_i_ff3 <= espi_cs_n_i_ff2;
   end
end

always @(posedge uart_clk or negedge espi_cs_n_i) begin
   if(!espi_cs_n_i) begin
      espi_alert_n <=1;
   end
   else begin
      if(espi_cs_n_i_ff3 && (uart_alert) && alert_en ) begin
         espi_alert_n <=0;
      end
   end
end
 
always @(posedge uart_clk or negedge espi_cs_n_i) begin
   if(!espi_cs_n_i) begin
      io1_alert_n <=1;
   end
   else begin
      if(espi_cs_n_i_ff3 && (uart_alert) && !alert_en ) begin
         io1_alert_n <=0;
      end
   end
end


wire [15:0] uart_status = {8'h1,1'b0,uart_int_status,6'h6};
wire [31:0] uart_intr_pedge = {8'h84,8'h0,8'h04,8'h0};
wire [15:0] uart_status_q = {1'b0,uart_int_status,6'h6,8'h1};
wire [31:0] uart_intr_pedge_q = {8'h0,8'h04,8'h0,8'h84};
wire [7:0] calc_crc = 8'hCC;
wire [7:0] vcount = 8'h1;
always @(negedge espi_clk or posedge espi_cs_n_i) begin
   if(espi_cs_n_i) begin
      espi_cpld_io0_o <=1'b0;
      espi_cpld_io1_o <=1'b0;
      espi_cpld_io2_o <=1'b0;
      espi_cpld_io3_o <=1'b0;
      espi_cpld_io0_oe <=0;
      espi_cpld_io1_oe <=0;
      espi_cpld_io2_oe <=0;
      espi_cpld_io3_oe <=0;
   end
   else if(espi_host_io_mode == SINGLE_IO) begin
      espi_cpld_io0_oe <=0;
      espi_cpld_io2_oe <=0;
      espi_cpld_io3_oe <=0;
      if(command == 8'h40) begin
         if( espi_addr[15:3] == 13'h7F) begin
            case(tx_shift_bit_cnt_m2[7:3])
               5'h2 : begin
                      espi_cpld_io1_o <= ACCEPT[7-tx_shift_bit_cnt_m2[2:0]];
                      espi_cpld_io1_oe <= 1'b1;
               end
               5'h3 : espi_cpld_io1_o <= uart_rddata[7-tx_shift_bit_cnt_m2[2:0]];
               5'h4 : espi_cpld_io1_o <= uart_status[7-tx_shift_bit_cnt_m2[2:0]];
               5'h5 : espi_cpld_io1_o <= uart_status[15-tx_shift_bit_cnt_m2[2:0]];
               5'h6 : espi_cpld_io1_o <= calc_crc[7-tx_shift_bit_cnt_m2[2:0]];
            endcase 
         end
         else begin
            case(tx_shift_bit_cnt_m2[7:3])
               5'h4 : begin
                    espi_cpld_io1_o <= uart_status[7-tx_shift_bit_cnt_m2[2:0]];
                    espi_cpld_io1_oe <= 1'b1;
               end
               5'h5 : espi_cpld_io1_o <= uart_status[15-tx_shift_bit_cnt_m2[2:0]];
               5'h6 : espi_cpld_io1_o <= calc_crc[7-tx_shift_bit_cnt_m2[2:0]];
            endcase 
         end
      end
      else if(command == 8'h44) begin
         if(espi_addr[15:3] == 13'h7F) begin
            case(tx_shift_bit_cnt_m2[7:3])
               5'h3 : begin
                      espi_cpld_io1_o <= ACCEPT[7-tx_shift_bit_cnt_m2[2:0]];
                      espi_cpld_io1_oe <= 1'b1;
               end
               5'h4 : espi_cpld_io1_o <= uart_status[7-tx_shift_bit_cnt_m2[2:0]];
               5'h5 : espi_cpld_io1_o <= uart_status[15-tx_shift_bit_cnt_m2[2:0]];
               5'h6 : espi_cpld_io1_o <= calc_crc[7-tx_shift_bit_cnt_m2[2:0]];
            endcase 
         end
         else begin
            case(tx_shift_bit_cnt_m2[7:3])
               5'h4 : begin
                    espi_cpld_io1_o <= uart_status[7-tx_shift_bit_cnt_m2[2:0]];
                    espi_cpld_io1_oe <= 1'b1;
               end
               5'h5 : espi_cpld_io1_o <= uart_status[15-tx_shift_bit_cnt_m2[2:0]];
               5'h6 : espi_cpld_io1_o <= calc_crc[7-tx_shift_bit_cnt_m2[2:0]];
            endcase 
         end
      end
      else if(command == 8'h05 && start_int) begin
          case(tx_shift_bit_cnt_m2[7:3])
             5'h0 : begin
                    espi_cpld_io1_o <= ACCEPT[7-tx_shift_bit_cnt_m2[2:0]];
                    espi_cpld_io1_oe <= 1'b1;
             end
             5'h1 : espi_cpld_io1_o <= vcount[7-tx_shift_bit_cnt_m2[2:0]];
             5'h2 : espi_cpld_io1_o <= uart_intr_pedge[7-tx_shift_bit_cnt_m2[2:0]];
             5'h3 : espi_cpld_io1_o <= uart_intr_pedge[15-tx_shift_bit_cnt_m2[2:0]];
             5'h4 : espi_cpld_io1_o <= uart_intr_pedge[23-tx_shift_bit_cnt_m2[2:0]];
             5'h5 : espi_cpld_io1_o <= uart_intr_pedge[31-tx_shift_bit_cnt_m2[2:0]];
             5'h6 : espi_cpld_io1_o <= uart_status[7-tx_shift_bit_cnt_m2[2:0]];
             5'h7 : espi_cpld_io1_o <= uart_status[15-tx_shift_bit_cnt_m2[2:0]];
             5'h8 : espi_cpld_io1_o <= calc_crc[7-tx_shift_bit_cnt_m2[2:0]];
         endcase
      end
      else if(command == 8'h25 && start_int) begin
          case(tx_shift_bit_cnt_m2[7:3])
             5'h0 : begin
                    espi_cpld_io1_o <= ACCEPT[7-tx_shift_bit_cnt_m2[2:0]];
                    espi_cpld_io1_oe <= 1'b1;
             end
             5'h1 : espi_cpld_io1_o <= uart_status[7-tx_shift_bit_cnt_m2[2:0]];
             5'h2 : espi_cpld_io1_o <= uart_status[15-tx_shift_bit_cnt_m2[2:0]];
             5'h3 : espi_cpld_io1_o <= calc_crc[7-tx_shift_bit_cnt_m2[2:0]];
         endcase
      end
      else begin
          espi_cpld_io1_oe <= 1'b0;
      end
   end
   else begin //quad io
      if(command == 8'h40) begin
         if( espi_addr[15:3] == 13'h7F) begin
            case(tx_shift_bit_cnt)
               8'h9,8'hA : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               8'hB,8'hC : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= uart_rddata[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= uart_rddata[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= uart_rddata[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= uart_rddata[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               8'hD,8'hE,8'hF,8'h10 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}  ];
                  espi_cpld_io1_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+1];
                  espi_cpld_io2_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+2];
                  espi_cpld_io3_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+3];
               end
               8'h11,8'h12 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               default : begin
                  espi_cpld_io0_oe <=1'b0;
                  espi_cpld_io1_oe <=1'b0;
                  espi_cpld_io2_oe <=1'b0;
                  espi_cpld_io3_oe <=1'b0;
               end
            endcase
         end
         else begin
            case(tx_shift_bit_cnt)
               8'hD,8'hE,8'hF,8'h10 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}  ];
                  espi_cpld_io1_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+1];
                  espi_cpld_io2_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+2];
                  espi_cpld_io3_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+3];
               end
               8'h11,8'h12 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               default : begin
                  espi_cpld_io0_oe <=1'b0;
                  espi_cpld_io1_oe <=1'b0;
                  espi_cpld_io2_oe <=1'b0;
                  espi_cpld_io3_oe <=1'b0;
               end
            endcase
         end
      end
      else if(command == 8'h44) begin
         if(espi_addr[15:3] == 13'h7F) begin
            case(tx_shift_bit_cnt)
               8'hB,8'hC : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               8'hD,8'hE,8'hF,8'h10 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}  ];
                  espi_cpld_io1_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+1];
                  espi_cpld_io2_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+2];
                  espi_cpld_io3_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+3];
               end
               8'h11,8'h12 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               default : begin
                  espi_cpld_io0_oe <=1'b0;
                  espi_cpld_io1_oe <=1'b0;
                  espi_cpld_io2_oe <=1'b0;
                  espi_cpld_io3_oe <=1'b0;
               end
            endcase
         end
         else begin
            case(tx_shift_bit_cnt)
               8'hD,8'hE,8'hF,8'h10 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}  ];
                  espi_cpld_io1_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+1];
                  espi_cpld_io2_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+2];
                  espi_cpld_io3_o <= uart_status_q[{8'h10-tx_shift_bit_cnt,2'b0}+3];
               end
               8'h11,8'h12 : begin
                  espi_cpld_io0_oe <=1;
                  espi_cpld_io1_oe <=1;
                  espi_cpld_io2_oe <=1;
                  espi_cpld_io3_oe <=1;
                  espi_cpld_io0_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}  ];
                  espi_cpld_io1_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+1];
                  espi_cpld_io2_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+2];
                  espi_cpld_io3_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+3];
               end
               default : begin
                  espi_cpld_io0_oe <=1'b0;
                  espi_cpld_io1_oe <=1'b0;
                  espi_cpld_io2_oe <=1'b0;
                  espi_cpld_io3_oe <=1'b0;
               end
            endcase
         end
      end
      else if(command == 8'h05 && start_int) begin
         case(tx_shift_bit_cnt)
            8'h5,8'h6 : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}  ];
               espi_cpld_io1_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+1];
               espi_cpld_io2_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+2];
               espi_cpld_io3_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+3];
            end
            8'h7,8'h8 : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= vcount[{tx_shift_bit_cnt[0],2'b0}  ];
               espi_cpld_io1_o <= vcount[{tx_shift_bit_cnt[0],2'b0}+1];
               espi_cpld_io2_o <= vcount[{tx_shift_bit_cnt[0],2'b0}+2];
               espi_cpld_io3_o <= vcount[{tx_shift_bit_cnt[0],2'b0}+3];
            end
            8'h9,8'hA,8'hB,8'hC,8'hD,8'hE,8'hF,8'h10 : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= uart_intr_pedge_q[{8'h10-tx_shift_bit_cnt,2'b0}  ];
               espi_cpld_io1_o <= uart_intr_pedge_q[{8'h10-tx_shift_bit_cnt,2'b0}+1];
               espi_cpld_io2_o <= uart_intr_pedge_q[{8'h10-tx_shift_bit_cnt,2'b0}+2];
               espi_cpld_io3_o <= uart_intr_pedge_q[{8'h10-tx_shift_bit_cnt,2'b0}+3];
            end
            8'h11,8'h12,8'h13,8'h14 : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= uart_status_q[{8'h14-tx_shift_bit_cnt,2'b0}  ];
               espi_cpld_io1_o <= uart_status_q[{8'h14-tx_shift_bit_cnt,2'b0}+1];
               espi_cpld_io2_o <= uart_status_q[{8'h14-tx_shift_bit_cnt,2'b0}+2];
               espi_cpld_io3_o <= uart_status_q[{8'h14-tx_shift_bit_cnt,2'b0}+3];
            end
            8'h15,8'h16 : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}  ];
               espi_cpld_io1_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+1];
               espi_cpld_io2_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+2];
               espi_cpld_io3_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+3];
            end
            default : begin
               espi_cpld_io0_oe <=1'b0;
               espi_cpld_io1_oe <=1'b0;
               espi_cpld_io2_oe <=1'b0;
               espi_cpld_io3_oe <=1'b0;
            end
          endcase
       end
       else if(command == 8'h25 && start_int) begin
         case(tx_shift_bit_cnt)
            8'h5,8'h6 : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}  ];
               espi_cpld_io1_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+1];
               espi_cpld_io2_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+2];
               espi_cpld_io3_o <= ACCEPT[{tx_shift_bit_cnt[0],2'b0}+3];
            end
            8'h7,8'h8,8'h9,8'hA : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= uart_status_q[{8'hA-tx_shift_bit_cnt,2'b0}  ];
               espi_cpld_io1_o <= uart_status_q[{8'hA-tx_shift_bit_cnt,2'b0}+1];
               espi_cpld_io2_o <= uart_status_q[{8'hA-tx_shift_bit_cnt,2'b0}+2];
               espi_cpld_io3_o <= uart_status_q[{8'hA-tx_shift_bit_cnt,2'b0}+3];
            end
            8'hB,8'hC : begin
               espi_cpld_io0_oe <=1;
               espi_cpld_io1_oe <=1;
               espi_cpld_io2_oe <=1;
               espi_cpld_io3_oe <=1;
               espi_cpld_io0_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}  ];
               espi_cpld_io1_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+1];
               espi_cpld_io2_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+2];
               espi_cpld_io3_o <= calc_crc[{tx_shift_bit_cnt[0],2'b0}+3];
            end
            default : begin
               espi_cpld_io0_oe <=1'b0;
               espi_cpld_io1_oe <=1'b0;
               espi_cpld_io2_oe <=1'b0;
               espi_cpld_io3_oe <=1'b0;
            end
          endcase
       end

    end //quad io
end



           
//always @(posedge espi_clk or negedge espi_rst_n) begin
//   if(!espi_rst_n) bios_smi <= 1'b1;
//   else if(rx_shift_bit_cnt[7:3] == 4 &&  espi_host_io_mode == SINGLE_IO && command == 8'h44) begin
//      bios_smi <= !uart_wrdata[2];
//   end
//   else if(rx_shift_bit_cnt[7:2] == 2 &&  espi_host_io_mode == QUAD_IO && command == 8'h44) begin
//      bios_smi <= !uart_wrdata[2];
//   end
//   else begin
//      bios_smi <= 1'b1;
//   end
//end

wire [7:0] rx_shift_bit_cnt_m = rx_shift_bit_cnt -2;
reg [7:0] intr_data;
always @(posedge espi_clk or negedge espi_rst_n) begin
   if(!espi_rst_n) intr_data <= 8'h0;
   else if(espi_host_io_mode == SINGLE_IO && command == 8'h05) begin
      if(rx_shift_bit_cnt_m[7:3] == 5 ) intr_data[7:0]<={intr_data[6:0],espi_host_io1_i};
   end
   else if(espi_host_io_mode == QUAD_IO && command == 8'h05) begin
      if(rx_shift_bit_cnt_m[7:1] == 5 ) intr_data[7:0]<= {intr_data[3:0],espi_host_io3_i,espi_host_io2_i,espi_host_io1_i,espi_host_io0_i};
   end
   else begin
      intr_data <= 8'b0;
   end
end   

//wire [7:0] uart_clk_divisor =76;//for uart_clk=140M
wire [7:0] uart_clk_divisor =72;//for uart_clk=133M

uart_cpld uart_cpld(                       
.uart_clk         (uart_clk),                            
.uart_rst_n       (uart_rst_n),                       
.uart_slave_addr  ({1'b0,espi_addr[2:0]}),            
.uart_slave_write (uart_wren),           
.uart_slave_read  (uart_ren ),            
.uart_slave_wrdata(uart_wrdata),          
.uart_slave_rddata(uart_rdout),          
.luart_sol_sw     (1'b0),                            
.clk_divisor      (uart_clk_divisor),               
.receiver_wdata   (8'd0),                            
.rfifo_full       (),                                
.receiver_wen     (1'b0),                            
.remote_rfifo_full(1'b0),                                
.uart_tx_o        (uart_tx_o),                    
.uart_rx_i        (uart_rx_i),                  
.transmitter_rden (),                                
.transmitter_data_out ()  ,                                                      
//.dma_p2m_breq  (dma_p2m_breq[0]),             
//.dma_p2m_lbreq (dma_p2m_lbreq[0]),            
//.dma_p2m_clr   (dma_p2m_clr[0]),              
//.dma_p2m_tc    (dma_p2m_tc[0]),               
//.dma_m2p_breq  (dma_m2p_breq[0]),             
//.dma_m2p_clr   (dma_m2p_clr[0]),              
//.dma_m2p_tc    (dma_m2p_tc[0]),               
                                              
.cts_pad_i     (1'b0),              
.dsr_pad_i     (1'b0),              
.ri_pad_i      (1'b0 ),              
.dcd_pad_i     (1'b0),              
.rts_pad_o     (rts_pad_o),               
.dtr_pad_o     (dtr_pad_o),                          
.int_o         (uart_int)           
);                                       

endmodule      
